#pragma once
#include <windows.h>

namespace krryn{
namespace gui{
	class widget_helper_win32{
	public:
		static char *window_class();

		template<typename T>
		static void create_window(T &a_Initializer, HWND &a_hWnd, HDC &a_hDC){
			DWORD l_ExtraStyle = 0;
			DWORD l_Style = 0;
			HWND l_ParentWnd = (HWND)a_Initializer.m_Parent->handle();

			RECT l_WindowRect;
			l_WindowRect.left	= (LONG)a_Initializer.m_Left;
			l_WindowRect.right	= (LONG)a_Initializer.m_Width + a_Initializer.m_Left;
			l_WindowRect.top	= (LONG)a_Initializer.m_Top;
			l_WindowRect.bottom	= (LONG)a_Initializer.m_Height + a_Initializer.m_Top;

			if(a_Initializer.m_Fullscreen){
				DEVMODE l_dmScreenSettings;
				memset(&l_dmScreenSettings, 0, sizeof(l_dmScreenSettings));
				l_dmScreenSettings.dmSize = sizeof(l_dmScreenSettings);
				l_dmScreenSettings.dmPelsWidth = a_Initializer.m_Width;
				l_dmScreenSettings.dmPelsHeight	= a_Initializer.m_Height;
				l_dmScreenSettings.dmBitsPerPel	= a_Initializer.m_BitsPerPixel;
				l_dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;

				if(ChangeDisplaySettings(&l_dmScreenSettings, CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL){
					// set parent window always on top and 
					// hides it's border / title bar / cursor et cetera
					SetWindowPos(
						l_ParentWnd, HWND_TOPMOST, 
						0, 0, 0, 0, SWP_NOREPOSITION | SWP_NOSIZE);
					SetWindowLong(l_ParentWnd, GWL_STYLE, WS_VISIBLE | WS_POPUP);
					SetWindowLong(l_ParentWnd, GWL_EXSTYLE, NULL);
					ShowCursor(FALSE);

					l_Style = WS_VISIBLE | WS_CHILD;
				}else{
					throw widget_exception("Can't change to fullscreen mode");
				}
			}else{
				l_Style = WS_VISIBLE | WS_CHILD;
			}

			AdjustWindowRectEx(&l_WindowRect, l_Style, FALSE, l_ExtraStyle);

			if (!(a_hWnd = CreateWindowEx(
				l_ExtraStyle, widget_helper_win32::window_class(), 
				"krryn::software_context", 
				l_Style | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 
				l_WindowRect.left, l_WindowRect.top, 
				l_WindowRect.right - l_WindowRect.left,
				l_WindowRect.bottom - l_WindowRect.top, 
				l_ParentWnd, NULL, NULL, NULL))){

					throw widget_exception("Failed to create window");
			}

			if(!(a_hDC = GetDC(a_hWnd))){
				throw widget_exception("Can't create opengl context");
			}
		}
	};
}
}